package com.example.serviceorder.config;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import feign.Logger;
import feign.Retryer;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

// 全局client的配置
@Configuration
@EnableFeignClients(basePackages = "com.example.serviceorder.feign")// 放在配置类上要加上openfeign客户端所在的包名
public class FeignGlobalConfig {

    @LoadBalanced// 使用第三种方式的时候开启这个。如果使用第一种和第二种方式，使用这个注解，那么会报错。
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    // NacosConfigManager类可以做到监听nacos配置的变化，这个类可以监听所有的nacos配置，不管他所在的服务的yaml文件是否有import那个配置都行，他都可以检测到。
    // @bean的方法形参中的对象Spring 会根据形参的类型（这里是 NacosConfigManager）从容器中查找对应的 Bean 并注入。默认按类型，如果类型去拿有多个会报错，需要配合@Qualifier才行
    // ApplicationRunner类的run方法在springboot启动的时候会自动执行，但是需要把这个ApplicationRunner类交给Spring容器管理才行。
    @Bean
    ApplicationRunner applicationRunner(NacosConfigManager manager){
        return args -> {
            ConfigService configService = manager.getConfigService();
            configService.addListener("service-order.properties", "DEFAULT_GROUP", new Listener() {
                @Override
                public Executor getExecutor() {
                    return Executors.newFixedThreadPool(4);
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                    System.out.println("配置发生变化！");
                    System.out.println("变化后的内容： " + configInfo);
                }
            });
        };
    }

    // 配置日志级别
    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }

    // 配置重试器
    @Bean
    Retryer retryer(){
        return new Retryer.Default();
    }

}
